package org.androbuzz;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ListActivity;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.database.MergeCursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class AndroBuzzFeedActivity extends ListActivity {
	
	private static final String TAG = "AndroBuzzFeedActivity";
	private TextView m_textView;
	private List<String> m_buddiesList = new ArrayList<String>();
	
	private AndroBuzzDbAdapter mDbHelper;
	
    /** The primary interface we will be calling on the service. */
    IAndroBuzzService mService = null;
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.feeds_list);
        
        mDbHelper = new AndroBuzzDbAdapter(this);
        Log.w(TAG, "opening db from feed !!!!!!!!!!!!");
        mDbHelper.open();
        
        getApplicationContext().bindService(new Intent(IAndroBuzzService.class.getName()),
                mConnection, Context.BIND_AUTO_CREATE);
        
        NotificationManager osnotif = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        osnotif.cancel(1); 
    }
	
	public void onDestroy(){
		super.onDestroy();
		
        // If we have received the service, and hence registered with
        // it, then now is the time to unregister.
        if (mService != null) {
            try {
            	Log.i(getClass().getSimpleName(), "Unregister callback");
                mService.unregisterCallback(mCallback);
            } catch (RemoteException e) {
                // There is nothing special we need to do if the service
                // has crashed.
            }
        }

        getApplicationContext().unbindService(mConnection);
		
		mDbHelper.close();
	}
	
	public void onStart() {
		super.onStart();
        
        fillData();
	}
	
	private void fillData() {
		loadBuddies();
		
		if(m_buddiesList.size() > 0)
		{
			Cursor buzzesCursor = mDbHelper.fetchAllBuzzes(m_buddiesList);
	        startManagingCursor(buzzesCursor);  
	        this.setListAdapter(new AndroBuzzBuzzListAdaptor(this, buzzesCursor));
		}
    }
	
	public String getUrlData(String url) {
		  String websiteData = null;
		  try {
			  DefaultHttpClient client = new DefaultHttpClient();
			  URI uri = new URI(url);
			  HttpGet method = new HttpGet(uri);
			  HttpResponse res = client.execute(method);
			  InputStream data = res.getEntity().getContent();
			  websiteData = generateString(data);
		  } catch (ClientProtocolException e) {
			  // TODO Auto-generated catch block
			  m_textView.setText("Client protocol exception");
			  e.printStackTrace();
		  } catch (IOException e) {
			  m_textView.setText("I/O exception:\n" + e.toString());
			  // TODO Auto-generated catch block
			  e.printStackTrace();
		  } catch (URISyntaxException e) {
			  m_textView.setText("URI syntax exception");
			  // TODO Auto-generated catch block
			  e.printStackTrace();
		  }
		  
		  return websiteData;
	}
	
	public String generateString(InputStream stream) {
		  InputStreamReader reader = new InputStreamReader(stream);
		  BufferedReader buffer = new BufferedReader(reader);
		  StringBuilder sb = new StringBuilder();
		  
		  try {
			  String cur;
			  while ((cur = buffer.readLine()) != null) {
				  sb.append(cur + "\n");
			  }
		  } catch (IOException e) {
			  m_textView.setText("I/O exception in generateString");
			  // TODO Auto-generated catch block
			  e.printStackTrace();
		  }
		  
		  try {
			  stream.close();
		  } catch (IOException e) {
			  m_textView.setText("I/O exception when closing stream");
			  // TODO Auto-generated catch block
			  e.printStackTrace();
		  }
		  return sb.toString();
	}
	
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the service object we can use to
            // interact with the service.  We are communicating with our
            // service through an IDL interface, so get a client-side
            // representation of that from the raw service object.
            mService = IAndroBuzzService.Stub.asInterface(service);

            // We want to monitor the service for as long as we are
            // connected to it.
            try {
                mService.registerCallback(mCallback);
            } catch (RemoteException e) {
                // In this case the service has crashed before we could even
                // do anything with it; we can count on soon being
                // disconnected (and then reconnected if it can be restarted)
                // so there is no need to do anything here.
            }
        }

        public void onServiceDisconnected(ComponentName className) {
        	Log.i(getClass().getSimpleName(), "Crash");
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
        }
    };
    
 // ----------------------------------------------------------------------
    // Code showing how to deal with callbacks.
    // ----------------------------------------------------------------------
    private static final int NEW_BUZZ_MSG = 1;
    private static final int REFRESH_BUZZ_MSG = 2;
    /**
     * This implementation is used to receive callbacks from the remote
     * service.
     */
    private IAndroBuzzServiceCallback mCallback = new IAndroBuzzServiceCallback.Stub() {
        /**
         * This is called by the remote service regularly to tell us about
         * new values.  Note that IPC calls are dispatched through a thread
         * pool running in each process, so the code executing here will
         * NOT be running in our main thread like most other things -- so,
         * to update the UI, we need to use a Handler to hop over there.
         */
        public void newBuzz(List<String> ids) {
            mHandler.sendMessage(mHandler.obtainMessage(NEW_BUZZ_MSG, ids));
        }
        
        public void refreshOnNewBuzz()
        {
        	mHandler.sendMessage(mHandler.obtainMessage(REFRESH_BUZZ_MSG));
        }
    };
    
    //not used anymore
    private void addOnList(String buzz_id)
    {
    	Log.i(getClass().getSimpleName(), "Received message val: " + buzz_id);

        long buzzid = mDbHelper.findBuzzByGoogleBuzzId(buzz_id);
        if(buzzid != -1)
        {

        	Cursor newBuzzCursor = mDbHelper.fetchBuzz(buzzid);
        	if(newBuzzCursor.getCount() > 0)
        	{
	        	Log.i(getClass().getSimpleName(), "add new buzz" + newBuzzCursor.getCount());
	        	
	        	SimpleCursorAdapter currentAdapter = (SimpleCursorAdapter)getListAdapter();
	        	//AndroBuzzWebViewCursorAdapter currentAdapter = (AndroBuzzWebViewCursorAdapter)getListAdapter();
	        	Cursor firstcursor = currentAdapter.getCursor();
	        	Cursor[] cursorTab = {newBuzzCursor, firstcursor};
	        	MergeCursor merger = new MergeCursor(cursorTab);
		        startManagingCursor(newBuzzCursor);
		        startManagingCursor(merger);
	
//		        setListAdapter(new SimpleCursorAdapter(this, R.layout.feed_row, merger, fromFields, fieldsToView));
		        this.setListAdapter(new AndroBuzzBuzzListAdaptor(this, merger));
		       // setListAdapter(new AndroBuzzWebViewCursorAdapter(this, merger));
        	}
        	else
        		Log.i(getClass().getSimpleName(), "Buzz can not be fetch");
        }
        else
        	Log.i(getClass().getSimpleName(), "Buzz not found in db");
    }
    
    private void reloadList()
    {
    	AndroBuzzBuzzListAdaptor currentAdapter = (AndroBuzzBuzzListAdaptor)getListAdapter();
    	if(currentAdapter != null)
    	{
	    	Cursor firstcursor = currentAdapter.getCursor();
	    	firstcursor.requery();
    	}
    	else
    		fillData();
    }
    
    private void loadBuddies()
    {
		AndroBuzzAccount account = new AndroBuzzAccount(getApplicationContext());
		
		m_buddiesList.clear();
		
		Log.i(getClass().getSimpleName(), "Get string account.getUsername: " + account.getUsername());	
		m_buddiesList.add(account.getUsername());
		
		String curProfile = mDbHelper.findCurrentProfileId();
		if(curProfile.length() > 0)
		{
			Cursor curBuddies = mDbHelper.findBuddiesByName(curProfile);
			if (curBuddies.getCount() > 0) {
				curBuddies.moveToFirst();
				do {
					m_buddiesList.add(curBuddies.getString(curBuddies.getColumnIndex("email")).replace("@gmail.com", ""));
				}while (curBuddies.moveToNext());
			}
			curBuddies.close();
		}
		else
			Log.e(getClass().getSimpleName(), "Cannot get current profile in service !");   	
    }
    
    private Handler mHandler = new Handler() {
        @Override public void handleMessage(Message msg) {
            switch (msg.what) {
                case REFRESH_BUZZ_MSG:
                	//addOnList(msg.obj.toString());
                	reloadList();
                	//call to add buzz in list here
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
        
    };
}
